home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / LL_LAND.ZIP / LL_FRAC.C < prev    next >
C/C++ Source or Header  |  1993-05-06  |  16KB  |  468 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4. #include <time.h>
  5. #include <math.h>
  6.  
  7. #define SNOW_MATERIAL   "WHITE MATTE"
  8. #define WATER_MATERIAL  "BLUE GLASS"
  9. #define GRASS_MATERIAL  "GREEN MATTE"
  10. #define ROCK_MATERIAL   "BEIGE MATTE"
  11.  
  12. #define RAND_FNC        rand()
  13.  
  14. #define SIZE (unsigned long)((1 << ITER))
  15. #define VARI (float)pow((double)VARI_CHANGE,(double)ITER)
  16.  
  17. char    FTYPE;
  18. short   ITER=4;
  19. short   MATERIAL=1;
  20. float   VARI_CHANGE=2.00;
  21. float   SEA=0.40;
  22. float   SNOW=1.00;
  23. short   XSIZE=200;
  24. short   YSIZE=200;
  25. short   ZSIZE=200;
  26. float   x_pos;
  27. float   y_pos;
  28. unsigned long count1;
  29. unsigned long count2;
  30. unsigned long buf_size;
  31. unsigned long faces;
  32. FILE  *handle;
  33. float huge *map;
  34. float snow;
  35. float water;
  36. float altitude;
  37. float min;
  38. float max;
  39. char  filename[81];
  40.  
  41. void iterate(long,long,long,long,float,float huge *);
  42. void write_material(FILE *,
  43.             unsigned long,
  44.             unsigned long, unsigned long,
  45.             float huge *,
  46.             float, float, float);
  47.  
  48. int write_faces(FILE *hand, char FTYPE)
  49. {
  50.     if (FTYPE==0)
  51.     {
  52.         fprintf(hand,"Face list:\n");
  53.         for (count1=0; count1<SIZE-1; count1++)
  54.             for (count2=0; count2<SIZE-1; count2++)
  55.             {
  56.                 fprintf(hand,"Face %lu:    A:%lu B:%lu C:%lu AB:1 BC:1 CA:1\n",
  57.                     count1*((SIZE-1)<<1)+count2*2,
  58.                     count1*SIZE+count2,
  59.                     count1*SIZE+count2+1,
  60.                     (count1+1)*SIZE+count2);
  61.                 if (MATERIAL)
  62.                     write_material(hand,
  63.                         count1*SIZE+count2,
  64.                         count1*SIZE+count2+1,
  65.                         (count1+1)*SIZE+count2,
  66.                         map,water,snow,altitude);
  67.                 fprintf(hand,"Face %lu:    A:%lu B:%lu C:%lu AB:1 BC:1 CA:1\n",
  68.                     count1*((SIZE-1)<<1)+count2*2+1,
  69.                     count1*SIZE+count2+1,
  70.                     (count1+1)*SIZE+count2+1,
  71.                     (count1+1)*SIZE+count2);
  72.                 if (MATERIAL)
  73.                     write_material(hand,
  74.                         count1*SIZE+count2+1,
  75.                         (count1+1)*SIZE+count2+1,
  76.                         (count1+1)*SIZE+count2,
  77.                         map,water,snow,altitude);
  78.             }
  79.     }
  80.  
  81.     return 0;
  82. }
  83.  
  84.  
  85. int     write_verts(FILE *hand, char FTYPE)
  86. {
  87.     if (FTYPE==0)
  88.     {
  89.         fprintf(hand,"Vertex list:\n");
  90.         for (count1=0; count1<SIZE; count1++)
  91.             for (count2=0; count2<SIZE; count2++)
  92.                 fprintf(hand,"Vertex %lu:  X: %f     Y: %f     Z: %f\n",
  93.                     count1*SIZE+count2,
  94.                     (float)(count2*XSIZE)/SIZE,(float)(count1*YSIZE)/SIZE,
  95.                     (float)(map[count1*SIZE+count2]*ZSIZE)/altitude);
  96.     }
  97.  
  98.     if (FTYPE==1)
  99.     {
  100.         fprintf(hand,"\tLL_DATA\t");
  101.         for (count1=0; count1<SIZE*8; count1++)
  102.         {
  103.             fprintf(hand,"db ");
  104.             for (count2=0; count2<SIZE/8-1; count2++)
  105.                 fprintf(hand,"%2u,",(unsigned char)((float)((map[count1*(SIZE/8)+count2]-water)*ZSIZE)/altitude));
  106.             fprintf(hand,"%2u\n\t\t",(unsigned char)((float)((map[count1*(SIZE/8)+count2]-water)*ZSIZE)/altitude));
  107.         }
  108.     }
  109.  
  110.     return 0;
  111. }
  112.  
  113. FILE *init_file(char *fname,char FTYPE)
  114. {
  115. FILE *hand;
  116.     if ((hand=fopen(fname,"wt"))==0)
  117.         return 0;
  118.  
  119.     if (FTYPE==0)
  120.     {
  121.         fprintf(hand,"Ambient light color: Red=0.3 Green=0.3 Blue=0.3\n\n");
  122.         fprintf(hand,"Named object: \"Fractal Mtn\"\n");
  123.         fprintf(hand,"Tri-mesh, Vertices: %lu     Faces: %lu\n",buf_size,faces);
  124.     }
  125.     if (FTYPE==1)
  126.     {
  127.         fprintf(hand,";;\n");
  128.         fprintf(hand,";; Lord Logics Landscape Mesh File\n");
  129.         fprintf(hand,";;\n");
  130.         fprintf(hand,".fardata\tLL_MESH\n");
  131.     }
  132.  
  133.     return hand;
  134. }
  135.  
  136.  
  137. main(int argc, char *argv[])
  138. {
  139.     strcpy(filename,"");
  140.  
  141.     for (count1=1; count1<argc; count1++)
  142.     {
  143.         if ((argv[count1][0]!='\\') && (argv[count1][0]!='/') && (argv[count1][0]!='-'))
  144.         {
  145.             printf("3D Fractal Landscape Creator v1.5                   [12-08-92]\n");
  146.             printf("Copyright (C) 1992-93 James P. Ketrenos\n\n");
  147.             printf("Valid Command Line Options:\n");
  148.             printf(" -nFileame.ext   [default: FRACTAL.???   ]\n");
  149.             printf(" -iIterations    [default: 4             ]\n");
  150.             printf(" -mMaterials     [default: 1 (ON)        ]\n");
  151.             printf(" -wWaterLevel    [default: 0.40          ]\n");
  152.             printf(" -sSnowLevel     [default: 1.00          ]\n");
  153.             printf(" -vVariable      [default: 2.00          ]\n");
  154.             printf(" -xSize          [default: 200           ]\n");
  155.             printf(" -ySize          [default: 200           ]\n");
  156.             printf(" -zSize          [default: 200           ]\n");
  157.             printf(" -tFileType      [default: 3D Studio .ASC]\n\n");
  158.             printf("Filename.ext consits of any valid DOS filename.  Up to 80 characters\n");
  159.             printf("             may be used to include path etc.  The file written is a\n");
  160.             printf("             3D Studio ASCII Text file and can get quite large.\n\n");
  161.             printf("Iterations   is an integer that can range from 1 to 15.  This is\n");
  162.             printf("             used to determine the number of splits performed.\n\n");
  163.             printf("Materials    is used to determine whether or not materials will\n");
  164.             printf("             assigned to faces or not.  1=ON 0=OFF.\n\n");
  165.             printf("<< Press any key to continue >>");
  166.             if (getch()==27)
  167.             {
  168.                 printf("\r                               \r");
  169.                 exit(0);
  170.             }
  171.             printf("\r                               \r");
  172.             printf("WaterLevel   is the percentage of the landform to make below the SEA\n");
  173.             printf("             LEVEL.  All land below this will be leveled to SEA.  It\n");
  174.             printf("             is entered as a decimal.  (1.00=All .. 0.25=1/4 etc.)\n\n");
  175.             printf("SnowLevel    is the percentage of the landform to make below the SNOW\n");
  176.             printf("             LEVEL.  All land above this will be WHITE.  This makes no\n");
  177.             printf("             plateau adjustments.  (1.00=All .. 0.25=1/4 etc.)\n\n");
  178.             printf("Variable     is the variable degredation of variance.  Basically, what\n");
  179.             printf("             this does is determine how much the variance will decrease\n");
  180.             printf("             with every land split.  Variable>1 will model \"life\".\n");
  181.             printf("             0<Variable<=1 will resemble \"chaos\".  Decent values can\n");
  182.             printf("             be found between 2.00 and 5.00.\n\n");
  183.             printf("Size         is the length of the box containing the landscape along\n");
  184.             printf("             perspective axis (X, Y, or Z).  It is better to keep the\n");
  185.             printf("             values semi-large (in the hundreds) to keep from having\n");
  186.             printf("             distortions due to round-off errors.\n\n");
  187.             printf("<< Press any key to continue >>");
  188.             if (getch()==27)
  189.             {
  190.                 printf("\r                               \r");
  191.                 exit(0);
  192.             }
  193.             printf("\r                               \r");
  194.             printf("Type         is the filetype to create.  Types are:\n");
  195.             printf("             0 - 3D Studio .ASC [default]\n");
  196.             printf("             1 - Lord Logics Landscape Data Mesh File .INC\n");
  197.             printf("                 Note: Iterations = 8, ZSize = 256\n");
  198.             printf("                       XSize = 256, and YSize = 256\n");
  199.             printf("                       Materials are OFF,\n");
  200.             printf("                       Snow is OFF Water is at 0.35\n\n");
  201.             printf("Any questions, comments, suggestions, donations, or information is welcome.\n");
  202.             printf("Mail to:\n\n");
  203.             printf("                James P. Ketrenos\n");
  204.             printf("                885 S.W. 84th Ct.\n");
  205.             printf("                Portland, OR  97225\n\n");
  206.             printf("Or e-mail at:  ketrenoj@ucs.orst.edu  up till 06-01-93.\n\n");
  207.             printf("If you would like to see the data output to a different file format\n");
  208.             printf("besides the 3D Studio ASCII file, then please send me a note saying\n");
  209.             printf("so along with a description of the file format and how it is made up.\n");
  210.             printf("Primarily I need to know how to define vertices and triangle faces.\n");
  211.             exit(0);
  212.         }
  213.  
  214.         switch(argv[count1][1]<'a' ? (argv[count1][1]-'A'+'a') : argv[count1][1])
  215.         {
  216.         case    'n':strcpy(filename,&argv[count1][2]); break;
  217.         case    'i':ITER=atoi(&argv[count1][2]); break;
  218.         case    'm':MATERIAL=atoi(&argv[count1][2]); break;
  219.         case    'w':SEA=atof(&argv[count1][2]); break;
  220.         case    's':SNOW=atof(&argv[count1][2]); break;
  221.         case    'v':VARI_CHANGE=atof(&argv[count1][2]); break;
  222.         case    'x':XSIZE=atoi(&argv[count1][2]); break;
  223.         case    'y':YSIZE=atoi(&argv[count1][2]); break;
  224.         case    'z':ZSIZE=atoi(&argv[count1][2]); break;
  225.         case    't':FTYPE=atoi(&argv[count1][2]); break;
  226.         default:argv[count1][0]='?';
  227.             count1--;
  228.         }
  229.     }
  230.  
  231.     if (filename[0]==0)
  232.         switch(FTYPE)
  233.         {
  234.         case 0:strcpy(filename,"FRACTAL.ASC"); break;
  235.         case 1:strcpy(filename,"FRACTAL.INC"); break;
  236.         }
  237.  
  238.     if (FTYPE==1)
  239.     {
  240.         MATERIAL=0;
  241.         SEA=0.35;
  242.         SNOW=1.00;
  243.         ITER=8;
  244.         ZSIZE=256;
  245.         XSIZE=YSIZE=256;
  246.     }
  247.  
  248.     printf("-=[      Fractal Landscape Creator      ]=-\n");
  249.     printf("           -=[ Version  1.5 ]=-\n\n");
  250.     printf("[         - Fractal Parameters -          ]\n");
  251.     printf("[ Matrix Splits         :    %-5u        ]",ITER);
  252.     if ((ITER>0) && (ITER<16))
  253.         printf("\n");
  254.     else
  255.     {
  256.         printf(" Invalid range!\n");
  257.         exit(-1);
  258.     }
  259.     printf("[ Matrix Base           :    %-4lu by %-4lu ]\n",SIZE,SIZE);
  260.     printf("[ Matrix Sea Level      :    %-4.2f         ]",SEA);
  261.     if ((SEA>=0.0) && (SEA<=1.0))
  262.         printf("\n");
  263.     else
  264.     {
  265.         printf(" Invalid range!\n");
  266.         exit(-1);
  267.     }
  268.     printf("[ Matrix Snow Level     :    %-4.2f         ]",SNOW);
  269.     if ((SNOW>=0.0) && (SNOW<=1.0))
  270.         printf("\n");
  271.     else
  272.     {
  273.         printf(" Invalid range!\n");
  274.         exit(-1);
  275.     }
  276.     printf("[ Variance Degredation  :    %-5.2f        ]",VARI_CHANGE);
  277.     if (VARI_CHANGE>0.0)
  278.         printf("\n");
  279.     else
  280.     {
  281.         printf(" Invalid range!\n");
  282.         exit(-1);
  283.     }
  284.     printf("[ Maximum Variance      :    %-7.2f      ]\n",VARI);
  285.     printf("[ Surface Vertices      :    %-8lu     ]\n",buf_size=SIZE*SIZE);
  286.     if (FTYPE!=1)
  287.     printf("[ Surface Faces         :    %-8lu     ]\n",faces=((SIZE-1)*(SIZE-1)*2));
  288.     printf("[ Cube Containment Size :(%-4ux%-4ux%-4u) ]",XSIZE,YSIZE,ZSIZE);
  289.     if ((XSIZE<=0.0) || (YSIZE<=0.0) || (ZSIZE<=0.0))
  290.     {
  291.         printf(" Invalid range!\n");
  292.         exit(-1);
  293.     }
  294.     printf("\n\n");
  295.  
  296.     printf("[      - Fractal Creation Progress -      ]\n");
  297.     printf("[ Initializing Matrix   :    WAIT.        ]");
  298.     if ((map=(float huge *)halloc(buf_size,sizeof(map[0])))==0)
  299.     {
  300.         printf(" Error!\n");
  301.         printf("          - Insufficient Memory -\n");
  302.         exit(-1);
  303.     }
  304.     for (count1=0; count1<buf_size; count1++)
  305.         map[count1]=(float)987;
  306.  
  307.     /* Initialize the four corners  */
  308.     srand((unsigned)time(0));       // Initialize the RNG
  309.     map[0*SIZE+0]=(float)((float)RAND_FNC/RAND_MAX) * VARI;
  310.     map[0*SIZE+(SIZE-1)]=(float)((float)RAND_FNC/RAND_MAX) * VARI;
  311.     map[(SIZE-1)*SIZE+(SIZE-1)]=(float)((float)RAND_FNC/RAND_MAX) * VARI;
  312.     map[(SIZE-1)*SIZE+0]=(float)((float)RAND_FNC/RAND_MAX) * VARI;
  313.  
  314.     printf("\r[ Initializing Matrix   :     OK.         ]\n");
  315.     printf("[ Creating Landscape    :    WAIT.        ]");
  316.     iterate(0,0,SIZE-1,SIZE-1,(float)VARI,map);
  317.     min=map[0];
  318.     max=map[0];
  319.     for (count1=1; count1<buf_size; count1++)
  320.     {
  321.         if (map[count1]<min) min=map[count1];
  322.         if (map[count1]>max) max=map[count1];
  323.     }
  324.     altitude=max-min;
  325.     printf("\r[ Creating Landscape    :     OK.         ]\n");
  326.     printf("[ Adding Elements       :    WAIT.        ]");
  327.     water=(float)altitude*SEA+min;
  328.     snow=(float)altitude*SNOW+min;
  329.     if (altitude==0.0)
  330.     {
  331.         printf(" Error!\n");
  332.         printf("No Landmass present.\n");
  333.         free(map);
  334.         exit(-2);
  335.     }
  336.  
  337.     for (count1=0; count1<buf_size; count1++)
  338.         if (map[count1]<=water)
  339.             map[count1]=water;
  340.  
  341.     printf("\r[ Adding Elements       :     OK.         ]\n\n");
  342.  
  343.     printf("[ Initializing Mesh File:    WAIT.        ]");
  344.     if ((handle=init_file(filename,FTYPE))==0)
  345.     {
  346.         printf("\r[ Initializing Mesh File:    ERROR!!      ]\n");
  347.         free(map);
  348.         exit(-1);
  349.     }
  350.     if (strlen(filename)>12)
  351.         printf("\r[ Initializing Mesh File: ...%-12s ]\n",&filename[strlen(filename)-12]);
  352.     else
  353.         printf("\r[ Initializing Mesh File:   %-12s  ]\n",filename);
  354.  
  355.  
  356.  
  357.     printf("[ Writing Vertices      :    WAIT.        ]");
  358.     if (write_verts(handle, FTYPE)==0)
  359.         printf("\r[ Writing Vertices      :     OK.         ]\n");
  360.     else
  361.     {
  362.         printf("\r[ Writing Vertices      :    ERROR!       ]\n");
  363.         close(handle);
  364.         free(map);
  365.         exit(-1);
  366.     }
  367.  
  368.     printf("[ Writing Faces         :    WAIT.        ]");
  369.     if (write_faces(handle, FTYPE)==0)
  370.         printf("\r[ Writing Faces         :     OK.         ]\n");
  371.     else
  372.     {
  373.         printf("\r[ Writing Faces         :    ERROR!       ]\n");
  374.         close(handle);
  375.         free(map);
  376.         exit(-1);
  377.     }
  378.  
  379.     printf("[ Closing Mesh File     :    WAIT.        ]");
  380.     fclose(handle);
  381.     printf("\r[ Closing Mesh File     :     OK.         ]\n");
  382.     free(map);
  383. }
  384.  
  385. void iterate(long c1, long c2, long c3, long c4, float variance, float huge *map)
  386. {
  387. long    longi;
  388. long    latit;
  389. float   height;
  390. float   change;
  391.  
  392.     if ((c3 - (c1 + 1)) & 1)
  393.         change=0.5;
  394.     else
  395.         change=0.0;
  396.  
  397.     longi=((c1 + c3) / 2);
  398.     latit=((c2 + c4) / 2);
  399.  
  400.     if (map[c2*SIZE+longi]==987)
  401.     {
  402.         height=((map[c2*SIZE+c1] + map[c2*SIZE+c3]) / 2);
  403.         height+=(float)((float)RAND_FNC/RAND_MAX) * variance - (variance * 0.5);
  404.         map[c2*SIZE+longi]=height+((map[c2*SIZE+c1]-height)*change)/((longi+change)-c1);
  405.     }
  406.  
  407.     if (map[c4*SIZE+longi]==987)
  408.     {
  409.         height=((map[c4*SIZE+c1] + map[c4*SIZE+c3]) / 2);
  410.         height+=(float)((float)RAND_FNC/RAND_MAX) * variance - (variance * 0.5);
  411.         map[c4*SIZE+longi]=height+((map[c4*SIZE+c1]-height)*change)/((longi+change)-c1);
  412.     }
  413.  
  414.     if (map[latit*SIZE+c1]==987)
  415.     {
  416.         height=((map[c2*SIZE+c1] + map[c4*SIZE+c1]) / 2);
  417.         height+=(float)((float)RAND_FNC/RAND_MAX) * variance - (variance * 0.5);
  418.         map[latit*SIZE+c1]=height+((map[c2*SIZE+c1]-height)*change)/((latit+change)-c2);
  419.     }
  420.  
  421.     if (map[latit*SIZE+c3]==987)
  422.     {
  423.         height=((map[c2*SIZE+c3] + map[c4*SIZE+c3]) / 2);
  424.         height+=(float)((float)RAND_FNC/RAND_MAX) * variance - (variance * 0.5);
  425.         map[latit*SIZE+c3]=height+((map[c2*SIZE+c3]-height)*change)/((latit+change)-c2);
  426.     }
  427.  
  428.     height=((map[c2*SIZE+c1] + map[c2*SIZE+c3] + map[c4*SIZE+c1] + map[c4*SIZE+c3] +
  429.         map[c2*SIZE+longi] + map[c4*SIZE+longi] + map[latit*SIZE+c1] + map[latit*SIZE+c3]) / 8);
  430.     height+=(float)((float)RAND_FNC/RAND_MAX) * variance - (variance * 0.5);
  431.  
  432.     if (change==0.5)
  433.         map[latit*SIZE+longi]=height+((map[c2*SIZE+c1]-height)*0.7071)/(1.4142*((longi+change)-c1));
  434.     else
  435.         map[latit*SIZE+longi]=height;
  436.  
  437.     if ((longi==c1) || (longi==c3) || (latit==c2) || (latit==c4)) return;
  438.  
  439.     iterate(c1, c2, longi, latit, (float)((longi-c1)*variance)/(((c3-c1)*VARI_CHANGE)/2), map);
  440.     iterate(longi, c2, c3, latit, (float)((c3-longi)*variance)/(((c3-c1)*VARI_CHANGE)/2), map);
  441.     iterate(c1, latit, longi, c4, (float)((latit-c2)*variance)/(((c4-c2)*VARI_CHANGE)/2), map);
  442.     iterate(longi, latit, c3, c4, (float)((c4-latit)*variance)/(((c4-c2)*VARI_CHANGE)/2), map);
  443.     return;
  444. }
  445.  
  446. void write_material(FILE *handle,unsigned long c1, unsigned long c2, unsigned long c3,float huge *map,
  447.     float water, float snow, float altitude)
  448. {
  449. float   average;
  450.  
  451.     average=(map[c1] + map[c2] + map[c3]) / 3;
  452.  
  453.     if (average >= snow)
  454.         fprintf(handle,"Material:\"%s\"\n",SNOW_MATERIAL);
  455.     else
  456.     if ((map[c1]==water) && (map[c2]==water) && (map[c3]==water))
  457.         fprintf(handle,"Material:\"%s\"\n",WATER_MATERIAL);
  458.     else
  459.     {
  460.         if ( ((fabs(map[c1]-average)*(ZSIZE/altitude)*2*SIZE/YSIZE)>4.5) ||
  461.              ((fabs(map[c2]-average)*(ZSIZE/altitude)*2*SIZE/YSIZE)>4.5) ||
  462.              ((fabs(map[c3]-average)*(ZSIZE/altitude)*2*SIZE/XSIZE)>4.5))
  463.             fprintf(handle,"Material:\"%s\"\n",ROCK_MATERIAL);
  464.         else
  465.             fprintf(handle,"Material:\"%s\"\n",GRASS_MATERIAL);
  466.     }
  467. }
  468.